/**
 * 应用请求库的工具类，该工具类必须存在，不可删除，可以根据具体的业务场景进行定制
 */
import store from "@/common/app/store.js";
import cacheKeys from "@/common/app/cacheKeys.js";
import utils from "@/common/app/utils.js";
import log from "@/common/app/log.js";

export default {
  /**
   * buildAppCustomeConfig 封装业务定制的接口请求参数，根据业务需要进行封装
   * @param {Object}  options 请求参数对象
   *                  {String}  url: 接口地址
   *                  {String}  method: http接口请求方式：GET、POST、DELETE、PUT、UPDATE
   *                  {any}     data: 接口请求数据，任意类型
   *                  {Object}  headers: 接口请求消息头参数配置
   *                  {String}  message: 接口错误的提示消息，如果该字段不为空，则当请求失败时，会在接口调用处处理错误消息的展示，业务侧则不需要进行消息提示处理
   *                  {Boolean} isMock: 当前接口是否需要使用本地模拟桩数据
   *                  {Boolean} unneedLog: 不需要打印接口日志，如果不传入该参数，默认会打印接口日志，如果某个接口响应的结果数据太大，该参数配置为true，不打印接口日志
   */
  buildAppCustomeConfig(options = {}) {
    const appVersion = store.getters.appVersion || {};
    options.headers = options.headers || {};

    options.headers["Content-Type"] = "application/json";
    options.headers["Client-Address"] = utils.getLocalIp();
    options.headers["Transaction"] = utils.randomString(10);
    options.headers["Version"] = appVersion.version || "1.0.0";
    // options.headers['Timestamp'] = new Date().getTime();
    // options.headers['Client-Type'] = store.getters.appChannel;
    // 如果当前请求没有设置不需要请求的token，则将token添加至请求头中
    if (!options.unneedToken) {
      const userTokenStr = store.getters.userToken;
      // 请求头中封装ticket字段
      if (userTokenStr && userTokenStr.length) {
        options.headers["token"] = userTokenStr;
      }
    }
    return options;
  },

  /**
   * 处理后台返回的响应信息
   */
  proccessResponse(res = {}, options = {}) {
    log.info(
      "处理后台接口的响应数据，响应数据为：",
      !options.unneedLog ? res : { message: "接口配置不打印响应体" }
    );
    // 收到后台响应请求后，优先缓存后台返回的token ========= 当前框架设计多层data结构，为适配后台数据结构
    if (
      res.data &&
      res.data.data &&
      res.data.data.data &&
      res.data.data.data.token &&
      res.data.data.data.token.length
    ) {
      store.commit(cacheKeys.CACHE_USER_TOKEN, res.data.data.data.token);
    }
    const resp = res.data || {};
    // 如果返回码为407，表示用户token失效，需要清空用户信息并退出登录
    // 如果返回码为406，表示后台已经将tonken清除，需要清空用户信息并退出登录
    // 如果返回码为401，表示用户未登录，需要清空用户信息并退出登录
    if (Number(resp.code) === 407 || Number(resp.code) === 406 || Number(resp.code) === 401) {
      store.dispatch("clearUserInfo");
      // 清空用户信息后，刷新页面以退出至登录页面
      window.location.reload();
      resp.message = "用户会话失效，请重新登录";
    }
    // 如果当前请求的blob文件流类型，则直接封装文件流返回
    if (options.responseType === "blob") {
      const fileStream = res.data;
      return {
        code: fileStream.size > 0 ? 200 : -1,
        success: fileStream.size > 0,
        message: fileStream.size > 0 ? '文件下载成功' : '文件下载失败',
        data: fileStream,
      };
    } else {
      return {
        code: resp.code,
        message: resp.message,
        timeStamp: resp.timeStamp,
        ...resp.data,
      };
    }
  },

  /**
   * 当前响应是否成功，不同的后台服务包含不同的响应结构，根据后台响应结构判断请求是否成功
   * @param {Object} res 当前接口的响应参数
   */
  isResponseSuccess(res = {}) {
    return res.success || (res && res.code === 0);
  },

  /**
   * 封装当前响应的错误消息，将后台返回的消息信息封装至框架响应的message字段中
   * @param {Object} res 当前接口的响应参数
   */
  getResponseMessage(res = {}, options = {}) {
    return (
      (res && res.message) ||
      res.msg ||
      res.description ||
      options.message ||
      "操作发生异常"
    );
  },
};
